﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.XPath;

namespace WFL.Windows.Forms.Theme
{
    public class AsmSkin : XmlSkinBase
    {
        private Assembly _assembly;
        private ResourceManager _resourceManager;

        public AsmSkin(Assembly assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }
            _assembly = assembly;
        }

        public override IList<SkinItem> GetList()
        {
            IList<SkinItem> list = null;
            string[] resources = _assembly.GetManifestResourceNames();
            string pattern = @"(^|\.)SkinList\.resources$";
            foreach (string resource in resources)
            {
                if (Regex.IsMatch(resource, pattern))
                {
                    string baseName = resource.Substring(0, resource.Length - 10);
                    ResourceManager resourceManager = new ResourceManager(baseName, _assembly);
                    string xml = resourceManager.GetString("_SkinList");
                    list = GetListFromXml(xml, delegate(string name) { return (Image)resourceManager.GetObject(name); });
                    break;
                }
            }
            return list;
        }

        protected override void LoadStyles(string id)
        {
            string[] resources = _assembly.GetManifestResourceNames();
            string pattern = @"(^|\.)" + id + @"\.resources$";
            foreach (string resource in resources)
            {
                if (Regex.IsMatch(resource, pattern))
                {
                    string baseName = resource.Substring(0, resource.Length - 10);
                    ResourceManager resourceManager = new ResourceManager(baseName, _assembly);
                    string xml = resourceManager.GetString("Skin");
                    LoadStylesFromXml(xml);
                    _resourceManager = resourceManager;
                    break;
                }
            }
        }

        protected internal override bool ChangeType(string value, Type targetType, out object result)
        {
            if (targetType == typeof(Image)
                || targetType == typeof(Bitmap)
                || targetType == typeof(Icon))
            {
                if (string.IsNullOrEmpty(value))
                {
                    result = null;
                    return true;
                }
                else
                {
                    result = _resourceManager.GetObject(value);
                    if (targetType.IsAssignableFrom(result.GetType()))
                    {
                        return true;
                    }
                    else
                    {
                        result = null;
                        return false;
                    }
                }
            }
            else if (targetType == typeof(string))
            {
                if (string.IsNullOrEmpty(value))
                {
                    result = value;
                    return true;
                }
                else if (value.StartsWith("$"))
                {
                    result = _resourceManager.GetString(value.Substring(1));
                    return true;
                }
                else
                {
                    if (Regex.IsMatch(value, @"^\\+\$"))
                    {
                        result = value.Substring(1);
                    }
                    else
                    {
                        result = value;
                    }
                    return true;
                }
            }
            else
            {
                return base.ChangeType(value, targetType, out result);
            }
        }
    }
}
